#pragma once

#include "InetAddr.hpp"
#include "mutex.hpp"
#include <list>
#include <memory>
#include <algorithm>
#include "log.hpp"

namespace UserManagerModule
{
    using namespace LockModule;
    using namespace LogModule;
    class UserInterface
    {
    public:
        virtual ~UserInterface() = default;
        virtual void Send(const std::string &message) = 0;
        virtual bool operator==(const InetAddr &u) = 0;
        virtual std::string Id() const = 0;
    };

    class User : public UserInterface
    {
    public:
        User(int sockfd,const InetAddr &id) :_sockfd(sockfd), _id(id) {}
        virtual void Send(const std::string &message) override
        {
            LOG(INFO) << "发送消息：" << message << "给" << _id.Addr();
            ::send(_sockfd, message.c_str(), message.size(), 0);
        }
        virtual bool operator==(const InetAddr &u) override
        {
            return _id == u;
        }
        virtual std::string Id() const override
        {
            return _id.Addr();
        }

    private:
        InetAddr _id;
        int _sockfd;
    };

    // 观察者模式
    class UserManager
    {
    public:
        void AddUser(int sock,const InetAddr &id)
        {
            LockGuard lg(_mutex);
            for (auto &pu : _online_user)
            {
                if (*pu == id)
                {
                    LOG(INFO) << id.Addr() << "用户已存在";
                    return;
                }
            }
            _online_user.push_back(std::make_shared<User>(sock,id));
            LOG(INFO) << "新增用户: " << id.Addr()<<"sockfd is"<<sock;
        }
        void DelUser(const InetAddr &id)
        {
            LockGuard lg(_mutex);
            LOG(INFO)<<"清除用户";
            //将不符合条件的全部移到队尾
            auto pos = std::remove_if(_online_user.begin(), _online_user.end(), [&id](const std::shared_ptr<UserInterface> &user)
                                      { return *user == id; });
            //一次性全删除
            _online_user.erase(pos,_online_user.end());
        }
        //推送服务
        void Router(const std::string& message)
        {
            LockGuard lg(_mutex);
            for(auto pu :_online_user)
            {
                pu->Send(message);
            }
             LOG(INFO)<<"推送完毕";
        }
        //查看用户列表
        void Printuser()
        {
            LockGuard lg(_mutex);
            for(auto pu :_online_user)
            {
                LOG(INFO)<<"用户在线: "<<pu->Id();
            }
        }
    private:
        std::list<std::shared_ptr<UserInterface>> _online_user;
        LockModule::Mutex _mutex;
    };
}
